#include "smse2kincludes.h"

CMemory::~CMemory() {
	if (memory) delete[] memory;
	if (mask)	delete[] mask;
}

CMemory::CMemory() {
	memory = NULL;	// The memory itself
	mask = NULL;	// Mask for code trace mode
	size = 0;

	writeprotect = 0;
	readprotect = 0;
	intracemode = 0;

	mem_initialized = 0;
}

UINT32 CMemory::GetSize() { 
	return this->size;
}

void CMemory::EnterTraceMode() {
	intracemode = 1;
}

UINT8* CMemory::GetRawMemory() {
	return memory;
}

int CMemory::CopyMemory(UINT8* block, UINT32 blksize) {
	if (!blksize) {
		Msg("Nothing to copy, moving on.\n");
		return 1;
	}


	// If we already have memory in this block, don't bother
	if (this->memory) {
		Msg("Cannot perform CopyMemory, memory has already been allocated\n");
		Msg("mem_initialized %d\n",mem_initialized);
		return 1;
	}

	// Copy!
	this->memory = new UINT8[blksize];
	this->size   = blksize;

	Msg("Copied 0x%08X bytes OK\n",blksize);

	return 0;
}

int CMemory::AllocMemory(UINT32 size) {
	this->memory = new UINT8[size];
	
	if (!memory) {
		Msg("Couldn't allocate %d bytes of memory\n",size);
		return 1;
	}

	if (this->intracemode) {
		this->mask = new UINT8[size];
		if (!mask) {
			Msg("Couldn't allocate %d bytes of memory for CMemory::mask. Trace mode disabled for this block\n",size);
			this->intracemode = 0; // exit trace mode
		}
	}

	Msg("Allocated 0x%08X bytes of memory OK\n",size);
	this->size = size;

	return 0;
}


UINT8 CMemory::Read8(UINT64 offset) {
	offset &= 0xffffffff; // I am not in the mood for you to be raping my memory thanks
	
	// catch a stupid
	if (offset > size) {
		Msg("Attempt to access data out of bounds: 0x%08X (max rom size 0x%08X)\n",offset,size);
		return 0;
	}

	// For code tracing
	if (intracemode) mask[offset] = 1;

	return memory[offset];
}